import 'package:dio/dio.dart';
import 'package:flutter_enjoy_plus_ghz/constants/index.dart';
import 'package:flutter_enjoy_plus_ghz/utils/Emitter.dart';
import 'package:flutter_enjoy_plus_ghz/utils/PrompAction.dart';
import 'package:flutter_enjoy_plus_ghz/utils/TokenManager.dart';

class RequestDio {
  // 有个地方可以设置dio的基础地址
  final Dio _dio = Dio();
  RequestDio() {
    // 针对dio的基础地址进行设置
    // _dio.options.baseUrl = GlobalVariable.BASE_URL; // 设置基础地址
    // _dio.options.receiveTimeout =
    //     const Duration(seconds: GlobalVariable.NET_WORK_TIME); // 接收时间
    // _dio.options.sendTimeout =
    //     const Duration(seconds: GlobalVariable.NET_WORK_TIME); // 发送超时时间
    _dio
      ..options.baseUrl = GlobalVariable.BASE_URL
      ..options.connectTimeout =
          const Duration(seconds: GlobalVariable.NET_WORK_TIME)
      ..options.receiveTimeout =
          const Duration(seconds: GlobalVariable.NET_WORK_TIME);

    // axios 和 rcp的拦截器
    // 添加请求和响应拦截器
    _registerInterceptors(); // 注册拦截器
  }
  _registerInterceptors() {
    _dio.interceptors.add(
      InterceptorsWrapper(
          // 请求拦截器
          onRequest: (request, handler) {
        // 在这里注入token
        var token = tokenManager.getToken();
        if (token != "") {
          request.headers["Authorization"] = "Bearer ${token}";
        }

        // request里面是请求参数
        handler.next(request);
      }, onResponse: (response, handler) {
        // response是响应结果
        // http业务状态码 200 -300 之间是成功的
        if (response.statusCode! >= 200 && response.statusCode! < 300) {
          handler.next(response); // 处理数据  这里可以处理错误
        } else {
          // 加401判断
          PromptAction.showError(response.statusMessage!); // 处理http 请求的问题
          handler.reject(DioException(requestOptions: response.requestOptions));
        }
      },
          // 错误拦截器
          onError: (exception, handler) async {
        if (exception.response?.statusCode == 401) {
          // 401 的处理
          String refreshToken = tokenManager.getRefreshToken();
          if (!refreshToken.isEmpty) {
            // 换token的方法
            bool isOK = await _refreshToken();
            if (isOK) {
              // 此时说明token已经换成功了啊
              // 之前的请求失败 把之前的请求发送回去
              //  exception.requestOptions 之前失败请求的参数的对象
              return handler.resolve(
                  await _dio.fetch(exception.requestOptions)); // 发送之前失败的请求
              // Promise -链式调用 -rejected -> 复活->resolve
            } else {
              // 彻底活不了
              tokenManager.removeToken(); // 删除token 跳转到登录页
              // emitter- eventBus
              // 事件监听 发布订阅
              // Navigator.push(context, route)
              // eventBus.fire(event);
              // eventBus.fire("abc");
              eventBus.fire(LogoutEvent());
            }
          } else {
            // 彻底活不了
            tokenManager.removeToken(); // 删除token 跳转到登录页
            // emitter- eventBus
            // 事件监听 发布订阅
            // Navigator.push(context, route)
            // eventBus.fire(event);
            // eventBus.fire("abc");
            eventBus.fire(LogoutEvent());
          }
        }
        handler.next(exception); // 抛出错误
      }),
    );
  }

  // 换取token
  Future<bool> _refreshToken() async {
    try {
      String refreshToken = tokenManager.getRefreshToken();
      Dio dio = Dio(); // 为什么要搞一个新的token
      var res = await dio.post('${GlobalVariable.BASE_URL}/refreshToken',
          options:
              Options(headers: {"Authorization": 'Bearer ${refreshToken}'}));
      if (res.data["code"] == GlobalVariable.SUCCESS_CODE) {
        // 说明请求成功
        tokenManager.setToken(res.data["data"]["token"],
            refreshToken: res.data["data"]["refreshToken"]);
        return true;
      } else {
        return false;
      }
    } catch (e) {
      return false;
    }
  }

  // 获取方法
  Future get(String url, {Map<String, dynamic>? params}) async {
    final result = await _dio.get(url, queryParameters: params);
    // 需要对数据进行二次处理
    return _handleResponse(result);
  }

  // 上传接口
  Future upload(String url, {FormData? data}) async {
    final result = await _dio.post(url, data: data);
    // 需要对数据进行二次处理
    return _handleResponse(result);
  }

  Future post(String url, {Map<String, dynamic>? data}) async {
    final result = await _dio.post(url, data: data);
    // 需要对数据进行二次处理
    return _handleResponse(result);
  }

  Future delete(String url,
      {Map<String, dynamic>? data, Map<String, dynamic>? params}) async {
    final result = await _dio.delete(url, queryParameters: params, data: data);
    // 需要对数据进行二次处理
    return _handleResponse(result);
  }

  Future put(String url,
      {Map<String, dynamic>? data, Map<String, dynamic>? params}) async {
    final result = await _dio.put(url, queryParameters: params, data: data);
    // 需要对数据进行二次处理
    return _handleResponse(result);
  }

  // 处理返回数据结构
  _handleResponse(Response<dynamic> result) {
    if (result.data["code"] == GlobalVariable.SUCCESS_CODE) {
      // 此时说明请求成功 返回正确的数据
      return result.data["data"];
    }
    PromptAction.showError(result.data["message"]);
    // 提示个消息 使用第三方插件的toast弹出
    throw Exception(result.data["message"]);
  }
}

final requestDio = RequestDio();

// 前端鸿蒙 axios - 对数据进行解构 return  data.result rcp 只能返回response
